home *** CD-ROM | disk | FTP | other *** search
/ Aminet 8 / Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso / Aminet / mus / play / tracker_4_31.lzh / tracker / notes.c < prev    next >
C/C++ Source or Header  |  1995-03-01  |  4KB  |  177 lines

  1. /* notes.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: notes.c,v 4.13 1995/03/01 15:24:51 espie Exp espie $
  6.  * $Log: notes.c,v $
  7.  * Revision 4.13  1995/03/01  15:24:51  espie
  8.  * *** empty log message ***
  9.  *
  10.  * Revision 4.12  1995/02/21  21:13:16  espie
  11.  * Cleaned up source. Moved minor pieces of code around.
  12.  *
  13.  * Revision 4.11  1995/02/21  17:54:32  espie
  14.  * Internal problem: buggy RCS. Fixed logs.
  15.  *
  16.  * Revision 4.9  1995/02/20  22:28:50  espie
  17.  * bug in nearest_note.
  18.  *
  19.  * Revision 4.8  1995/02/20  16:49:58  espie
  20.  * Added nearest_note: round pitch to nearest entire note.
  21.  *
  22.  * Revision 4.5  1995/02/01  16:39:04  espie
  23.  * Moved includes to defs.h
  24.  *
  25.  * Revision 4.0  1994/01/11  17:50:04  espie
  26.  * Makes use of autoinit. Uses less memory, starts up faster.
  27.  * auto_init'd create_notes_table(),
  28.  * suppressed note_name static table,
  29.  * use name_of_note() instead (about 120 * 8 bytes gain).
  30.  * Amiga support.
  31.  * Added finetune.
  32.  */
  33.  
  34. #include "defs.h"
  35.  
  36. #include <ctype.h>
  37. #include <assert.h>
  38. #include <math.h>
  39.  
  40. #include "song.h"
  41. #include "channel.h"
  42. #include "extern.h"
  43.  
  44. ID("$Id: notes.c,v 4.13 1995/03/01 15:24:51 espie Exp espie $")
  45.  
  46.  
  47. /* we can put it autoinit since find_note is ALWAYS called
  48.  * prior to using pitch_table !
  49.  */
  50. LOCAL void create_notes_table P((void));
  51. LOCAL void (*INIT)P((void)) = create_notes_table;
  52.  
  53.  
  54. /* the musical notes correspond to some specific pitch.
  55.  * It's useful to be able to find them back, at least for
  56.  * arpeggii.
  57.  */
  58. short pitch_table[NUMBER_NOTES][NUMBER_FINETUNES];
  59.  
  60. LOCAL char *note_template = "C-C#D-D#E-F-F#G-G#A-A#B-";
  61.  
  62. /* note = find_note(pitch): 
  63.  * find note corresponding to the stated pitch 
  64.  */
  65. int find_note(pitch)
  66. int pitch;
  67.    {
  68.    int a, b, i;
  69.    
  70.    INIT_ONCE;
  71.  
  72.    if (pitch == 0)
  73.       return -1;
  74.    a = 0;
  75.    b = NUMBER_NOTES-1;
  76.    while(b-a > 1)
  77.       {
  78.       i = (a+b)/2;
  79.       if (pitch_table[i][0] == pitch)
  80.          return i;
  81.       if (pitch_table[i][0] > pitch)
  82.          a = i;
  83.       else
  84.          b = i;
  85.       }
  86.    if (pitch_table[a][0] - FUZZ <= pitch)
  87.       return a;
  88.    if (pitch_table[b][0] + FUZZ >= pitch)
  89.       return b;
  90.    return NO_NOTE;
  91.    }
  92.  
  93. /* pitch = nearest_note(pitch, finetune):
  94.  * return the pitch corresponding to the nearest note for the given
  95.  * finetune
  96.  */
  97. int nearest_note(pitch, finetune)
  98. int pitch;
  99. int finetune;
  100.     {
  101.    int a, b, i;
  102.    
  103.    INIT_ONCE;
  104.  
  105.    if (pitch == 0)
  106.       return -1;
  107.    a = 0;
  108.    b = NUMBER_NOTES-1;
  109.    while(b-a > 1)
  110.       {
  111.       i = (a+b)/2;
  112.       if (pitch_table[i][finetune] == pitch)
  113.          return pitch;
  114.       if (pitch_table[i][finetune] > pitch)
  115.          a = i;
  116.       else
  117.          b = i;
  118.       }
  119.             /* need some check for the actual nearest note ? */
  120.     return pitch_table[i][finetune];
  121.    }
  122.  
  123.  
  124. LOCAL void create_notes_table()
  125.    {
  126.    double base, pitch;
  127.    int i, j, k;
  128.  
  129.    for (j = -8; j < 8; j++)
  130.       {
  131.       k = j < 0 ? j + 16 : j;
  132.       base = AMIGA_CLOCKFREQ/440.0/4.0 / pow(2.0, j/96.0);
  133.  
  134.       for (i = 0; i < NUMBER_NOTES; i++)
  135.          {
  136.          pitch = base / pow(2.0, i/12.0);
  137.          pitch_table[i][k] = floor(pitch + 0.5);
  138.          }
  139.       }
  140.     }
  141.  
  142. char *name_of_note(i)
  143. int i;
  144.    {
  145.    static char name[4];
  146.  
  147.    if (i == NO_NOTE)
  148.       return "   ";
  149.    else 
  150.       {
  151.       name[0] = note_template[(i+9)%12 * 2];
  152.       name[1] = note_template[(i+9)%12 * 2 +1];
  153.       name[2] = '0' + (i-3)/12;
  154.       name[3] = 0;
  155.       return name;
  156.       }
  157.    }
  158.    
  159. int transpose_song(s, transpose)
  160. struct song *s;
  161. int transpose;
  162.    {
  163.    int oldt;
  164.    int i, j, n;
  165.  
  166.    if (!s)
  167.       return 0;
  168.    oldt = s->info.transpose;
  169.    for (n = 0; n < s->info.maxpat; n++)
  170.       for (i = 0; i < s->info.plength; i++)
  171.          for (j = 0; j < s->ntracks; j++)
  172.             if (s->info.pblocks[n].e[j][i].note != NO_NOTE)
  173.                s->info.pblocks[n].e[j][i].note += transpose - oldt;
  174.    s->info.transpose = transpose;
  175.    return oldt;
  176.    }
  177.